import * as pako from 'pako';
import moment from 'moment';
import { getResourceCode, getUser } from './user-util';
import XEUtils from 'xe-utils';
// eslint-disable-next-line camelcase
import { yh_message_warn } from '@yhfin/biz/components/yh-message';
import Axios from 'axios';
import { TagsViewModule } from '@/store/modules/tags-view';

export const UUID = () => {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
};

export const UUID12 = () => {
    return (
        (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) +
        '-' +
        (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) +
        '-' +
        (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
    );
};

/**
 * 数据分页功能
 * @param data 需要分页的数据
 * @param currentpage 当前页
 * @param pageSize 每页个数
 * @return 分页后的新数据
 */
export const getCurrentPageData = (data: any[], currentpage: number, pageSize: number): any[] => {
    return (data || []).slice((currentpage - 1) * pageSize, currentpage * pageSize);
};

/**
 * 获取文件的文本
 * @param file 要解析的文件
 */
export const getFileText = (file: File): Promise<any> => {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = evt => {
            resolve(reader.result);
        };
        reader.onerror = evt => {
            reject(reader.error);
        };
        reader.readAsText(file);
    });
};

/**
 * 补0方法
 */
export function PrefixInteger(num, length) {
    if (String(num).length >= length) {
        return num;
    }
    return (Array(length).join('0') + num).slice(-length);
}

/**
 * 转大写中文
 */
export const NumberToWords = (n: string): string => {
    /*  if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(n))
         return "数据非法"; */
    if (!/^(0|-*[1-9]\d*)(\.\d+)?$/.test(n)) {
        return '';
    }
    const fuhao = n.toString().indexOf('-') === 0 ? '负' : '';

    let unit = '百拾万千百拾亿千百拾万千百拾元角分';
    let str = '';
    n += '00';
    // 如果是负数就就截取
    if (fuhao === '负') {
        n = n.substring(1, n.length);
    }
    const p = n.indexOf('.');
    if (p >= 0) n = n.substring(0, p) + n.substr(p + 1, 2);
    unit = unit.substr(unit.length - n.length);
    for (let i = 0; i < n.length; i++) str += '零壹贰叁肆伍陆柒捌玖'.charAt(Number(n.charAt(i))) + unit.charAt(i);
    return (
        fuhao +
        str
            .replace(/零(千|百|拾|角)/g, '零')
            .replace(/(零)+/g, '零')
            .replace(/零(万|亿|元)/g, '$1')
            .replace(/(亿)万|壹(拾)/g, '$1$2')
            .replace(/^元零?|零分/g, '')
            .replace(/元$/g, '元整')
    );
};

/**
 * @desc 函数防抖
 * @param func 目标函数
 * @param wait 延迟执行毫秒数
 * @param immediate true - 立即执行， false - 延迟执行
 */
export const debounce = (func: any, wait: number, immediate: boolean): any => {
    let timer;
    return function () {
        const context = this;
        // eslint-disable-next-line prefer-rest-params
        const args = arguments;

        if (timer) clearTimeout(timer);
        if (immediate) {
            const callNow = !timer;
            timer = setTimeout(() => {
                timer = null;
            }, wait);
            if (callNow) func.apply(context, args);
        } else {
            timer = setTimeout(() => {
                func.apply(context, args);
            }, wait);
        }
    };
};

// 字符串转base64
export function StringToBase64(str: string) {
    // 对字符串进行编码
    const encode = encodeURI(str);
    // 对编码的字符串转化base64
    const base64 = btoa(encode);
    return base64;
}

/**
 * 参数：b64Data 格式
 * 后台数据经过gzip进行压缩然后进行Base64进行编码 后的字符串
 * 返回：格式
 * 还原后的字符串
 */
export const GunDataGzip = (b64Data: any) => {
    // Decode base64 (convert ascii to binary)
    const strData = atob(b64Data);

    // Convert binary string to character-number array
    const charData = strData.split('').map(function (x) {
        return x.charCodeAt(0);
    });

    // Turn number array into byte-array
    const binData = new Uint8Array(charData);

    // Pako magic
    const data = pako.inflate(binData);
    return Utf8ArrayToStr(data);
    // Convert gunzipped byteArray back to ascii string:
    // var strData = String.fromCharCode.apply(null, new Uint16Array(data));
    // return strData;
};

function Utf8ArrayToStr(array: any) {
    let out, i, c;
    let char2, char3;
    out = '';
    const len = array.length;
    i = 0;
    while (i < len) {
        c = array[i++];
        switch (c >> 4) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                // 0xxxxxxx
                out += String.fromCharCode(c);
                break;
            case 12:
            case 13:
                // 110x xxxx 10xx xxxx
                char2 = array[i++];
                out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));
                break;
            case 14:
                // 1110 xxxx 10xx xxxx 10xx xxxx
                char2 = array[i++];
                char3 = array[i++];
                out += String.fromCharCode(((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0));
                break;
            default:
                break;
        }
    }
    return out;
}

/**
 * 格式化时间
 * @param str 时间
 * @param completion 是否补全时间，比如 '0' => '00:00:00'
 * @returns 格式化后的时间
 */
export function timeFormat(str: string | number, completion?: boolean, pattern = 'HH:mm:ss', self = 'HHmmss') {
    if ((!str || str === '0') && !completion) {
        return '';
    }
    let time;
    if (completion && !str) {
        time = '';
    } else {
        time = str.toString();
    }
    let count = self.length;
    if (time.length < count) {
        const addLen = count - time.length;
        for (let i = 0; i < addLen; i++) {
            time = '0' + time;
        }
    }

    return moment(time, self).format(pattern);
}

/**
 * 格式化日期
 * @param str 日期
 * @returns 格式化后的日期
 */
export function dateFormat(str: string | number, completion?: boolean) {
    if ((!str || str === '0') && !completion) {
        return '';
    } else if ((!str || str === '0') && completion) {
        return '0000-00-00';
    }
    let date = str.toString();
    if (date.length < 8) {
        const addLen = 8 - date.length;
        for (let i = 0; i < addLen; i++) {
            date = '0' + date;
        }
    }

    return moment(date, 'YYYYMMDD').format('YYYY-MM-DD');
}

/**
 * 千分位格式话
 * @param str 日期
 * @returns 格式化后的日期
 */
export function thousandsFormat(str: string | number) {
    if (str == undefined) return str;
    return str.toString().replace(/\d+/, n => {
        // 先提取整数部分
        return n.replace(/(\d)(?=(\d{3})+$)/g, $1 => {
            return $1 + ',';
        });
    });
}

/**
 * 千分位转数字
 * @param str 日期
 * @returns 格式化后的日期
 */
export function thousandsFormatToNumber(str: string) {
    if (str == undefined) return str;
    return str
        .toString()
        .replace(/,/gi, '')
        .replace(/[ ]/g, '');
}

/**
 * 保留小数位，并对数字进行千分位,可以直接传入单位（进行单位转换），也可以直接传入保留的小数位
 * 支持类型：
 * 数字 -> %
 * 股 -> 万股
 * 元 -> 万元
 * 元 -> 亿元
 * @param str 格式化
 * @param formatParam 可以传入单位，也可以传入保留的小数位
 */
export function numberFormat(number: any, formatParam?) {
    let value;
    if (number === undefined) {
        return '';
    }
    value = Number(number);
    if (formatParam == undefined || formatParam == '无') {
        return thousandsFormat(value);
    }
    let n;
    if (!isNaN(formatParam.toString()) && (n = Number(formatParam)) >= 0 && n % 1 == 0) {
        // value = value.toFixed(n); // toFixed()四舍五入精度处理有问题
        value = customToFixed(value, n);
    }
    switch (formatParam) {
        case '%':
            value = accMul(value, 100).toFixed(3);
            break;
        case '%%':
            value = accMul(value, 1000).toFixed(2);
            break;
        case '万股':
            value = (value / 10000).toFixed(2);
            break;
        case '万元':
            value = (value / 10000).toFixed(4);
            break;
        case '亿元':
            value = (value / 100000000).toFixed(2);
            break;
        case '元':
            value = customToFixed(value, 2);
            break;
        case '年':
            // 经确认 年 后台已处理
            // value = Math.floor(value / 365);
            value = customToFixed(value, 4);
            break;
        default:
            break;
    }
    return thousandsFormat(value);
}

/**
 * 信达澳亚 计算结果保留4位
 * @param number
 * @param formatParam
 * @returns
 */
export function numberFormatXDAY(number: any, formatParam?) {
    let value;
    if (number === undefined) {
        return '';
    }
    value = Number(number);
    if (formatParam == undefined || formatParam == '无') {
        value = Number(number).toFixed(4);
        return thousandsFormat(value);
    }
    let n;
    if (!isNaN(formatParam.toString()) && (n = Number(formatParam)) >= 0 && n % 1 == 0) {
        // value = value.toFixed(n); // toFixed()四舍五入精度处理有问题
        value = customToFixed(value, n);
    }
    switch (formatParam) {
        case '%':
            value = accMul(value, 100).toFixed(4);
            break;
        case '%%':
            value = accMul(value, 1000).toFixed(4);
            break;
        case '万股':
            value = (value / 10000).toFixed(4);
            break;
        case '万元':
            value = (value / 10000).toFixed(4);
            break;
        case '亿元':
            value = (value / 100000000).toFixed(4);
            break;
        case '元':
            value = customToFixed(value, 4);
            break;
        case '年':
            // 经确认 年 后台已处理
            // value = Math.floor(value / 365);
            value = customToFixed(value, 4);
            break;
        default:
            break;
    }
    return thousandsFormat(value);
}

/**
 * #11183 【兴业基金】（功能）系统页面阈值与结果展示优化
 * @param number
 * @param formatParam
 * @param thresholdValue 是否是阈值
 */
export function numberFormatCIB(number: any, formatParam?, thresholdValue?) {
    let value;
    if (number === undefined) {
        return '';
    }
    value = Number(number);
    if (formatParam == undefined || formatParam == '无') {
        if (thresholdValue) {
            return thousandsFormat(value); // 阈值且无单位时 保留原值
        }
        value = Number(number).toFixed(4);
        return thousandsFormat(value);
    }
    let n;
    if (!isNaN(formatParam.toString()) && (n = Number(formatParam)) >= 0 && n % 1 == 0) {
        // value = value.toFixed(n); // toFixed()四舍五入精度处理有问题
        value = customToFixed(value, n);
    }
    switch (formatParam) {
        case '%':
            value = accMul(value, 100).toFixed(4);
            break;
        case '万股':
            value = (value / 10000).toFixed(4);
            break;
        case '万元':
            value = (value / 10000).toFixed(4);
            break;
        case '亿元':
            value = (value / 100000000).toFixed(4);
            break;
        case '元':
            value = customToFixed(value, 4);
            break;
        case '天':
            value = customToFixed(value, 2);
            break;
        case '年':
            // 经确认 年 后台已处理
            // value = Math.floor(value / 365);
            value = customToFixed(value, 4);
            break;
        default:
            break;
    }
    return thousandsFormat(value);
}

/**
 * 乘法精度丢失问题
 */
export function accMul(arg1: any, arg2: number): number {
    if (arg1 === undefined || arg2 === undefined) {
        return undefined;
    }
    let m = 0;
    const s1 = arg1.toString();
    const s2 = arg2.toString();
    try {
        m += s1.split('.')[1].length;
    } catch (e) { }
    try {
        m += s2.split('.')[1].length;
    } catch (e) { }
    return (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) / Math.pow(10, m);
}

/**
 * 除法精度丢失问题
 */
export function accDiv(arg1, arg2) {
    let t1 = 0;
    let t2 = 0;

    try {
        t1 = arg1.toString().split('.')[1].length;
    } catch (e) { }
    try {
        t2 = arg2.toString().split('.')[1].length;
    } catch (e) { }
    const r1 = Number(arg1.toString().replace('.', ''));
    const r2 = Number(arg2.toString().replace('.', ''));
    const intDiv = r1 / r2;
    const pow = Math.pow(10, t2 - t1);
    return accMul(intDiv, pow); // 这里用上面定义好的乘法运算
}

/**
 * 输入显示格式化
 *
 * showType 支持类型：万元、 元、 亿、 数量类
 *
 * @param value     输入值
 * @param showType  显示类型
 */
export function formatInput(value: any, showType) {
    if (showType == undefined) {
        return value.toString();
    }
    switch (showType) {
        case '万元':
            if (Number(value) >= 10 ** 15) {
                return false;
            } else {
                return (Number(value) * 10000).toString();
            }
        case '元' || '数量类':
            if (Number(value) >= 10 ** 15) {
                return false;
            } else {
                return Number(value).toString();
            }
        case '亿':
            if (Number(value) >= 10 ** 15) {
                return false;
            } else {
                return (Number(value) * 100000000).toString();
            }
        default:
            break;
    }
    return value.toString();
}

export function unitShow(unit: string) {
    return unit !== undefined && unit.trim() && unit !== '无' ? unit : '';
}

/**
 * 保留小数位
 * @param str 需要处理的数值
 * @param precision 保留的小数位位数
 */
export function customToFixed(str: any, precision: number) {
    const formatter = new Intl.NumberFormat('en-US', {
        minimumFractionDigits: precision,
        maximumFractionDigits: precision,
    });
    return formatter.format(Number(str));
}

/**
 * 对象数组排序
 * @param sortBy 排序字段
 * @param sortType 排序方式
 */
export function sortBy(props, sortType) {
    return function (a, b) {
        if (sortType == 'desc') {
            return b[props] - a[props];
        } else {
            return a[props] - b[props];
        }
    };
}

/**
 * 格式化日期
 */
export function formatterDate(row, column, cellValue, index) {
    return dateFormat(cellValue) || '--';
}

/**
 * 格式化时间
 */
export function formatterTime(row, column, cellValue, index) {
    return timeFormat(cellValue) || '--';
}

/**
 * 格式化空值为'--'
 */
export function formatter(row, column, cellValue, index) {
    if (cellValue + '' === '0') {
        return '0';
    }
    return (cellValue && (cellValue + '').trim()) || '--';
}

/**
 * 格式化数字
 */
export function formatterNumber(row, column, cellValue, index) {
    return cellValue && (cellValue + '').trim() ? numberFormat(cellValue, 2) : '--';
}

/**
 * 对象数组去重
 */
export function uniqueFunc(arr, uniId) {
    const res = new Map();
    if (!arr) {
        return [];
    }
    return arr.filter(item => !res.has(item[uniId]) && res.set(item[uniId], 1));
}

/**
 * 转vxe-table表格筛选下拉框数据
 */
export function objToVxeFilterArr(param) {
    const list = [];
    for (const key in param) {
        list.push({ label: param[key], value: key });
    }
    return list;
}
/**
 * 获取下拉数据 根据已选择数据排序
 * @param key
 */
export function changeOptions(selectedData: any, optionsData: any, key: string) {
    const arr = [];
    selectedData &&
        selectedData.forEach(item => {
            const obj = optionsData.find(element => item == element[key]);
            if (obj) {
                arr.push(obj);
            }
        });
    const arrs = [...arr, ...optionsData];
    const map = new Map();
    for (const item of arrs) {
        if (!map.has(item[key])) {
            map.set(item[key], item);
        }
    }
    const newArr = [...map.values()];
    return newArr;
}

/**
 * 指令字段红绿凸显
 */
export function highlightColor() {
    return ['', 'red', 'green'];
}

/**
 * 根据权限显示
 * @Param
 */
export function checkPermission(resourceCode: string) {
    const resources = getUser().resources;
    if (!resourceCode || !resources || !resources.length) {
        return;
    }
    const itemValue = resources.find(item => {
        return item.resourceCode === resourceCode;
    });
    if (!itemValue) {
        return false;
    } else {
        return true;
    }
}

/**
 * 根据委托方向处理下拉框文字颜色
 * @param orderDirection
 * @returns 颜色
 */
export function handleTextColor(orderDirection: string) {
    if (['1', '3', '5', '98', 'F', 'U', 'P', 'X', 'V', 'D', 'p', 'C'].includes(orderDirection)) {
        return 'color: red';
    } else if (['2', '4', '6', 'i', 'l', 'T', 'Q', '9', 'A', 'B', 'Y', 'W', 'q'].includes(orderDirection)) {
        return 'color: green';
    } else {
        return '';
    }
}

export function convertNum(num) {
    // 参数必须为 字符串
    // 科学计数法字符 转换 为数字字符， 突破正数21位和负数7位的Number自动转换
    // 兼容 小数点左边有多位数的情况，即 a×10^b（aEb），a非标准范围（1≤|a|<10）下的情况。如 3453.54E-6 or 3453.54E6
    let resValue = '';
    let power;
    let result = null;
    let dotIndex = 0;
    let resArr = [];
    let sym = '';
    let numStr = num.toString();
    if (numStr[0] == '-') {
        // 如果为负数，转成正数处理，先去掉‘-’号，并保存‘-’.
        numStr = numStr.substr(1);
        sym = '-';
    }
    if (numStr.indexOf('E') != -1 || numStr.indexOf('e') != -1) {
        const regExp = new RegExp('^(((\\d+.?\\d+)|(\\d+))[Ee]{1}((-(\\d+))|(\\d+)))$', 'ig');
        result = regExp.exec(numStr);
        if (result != null) {
            resValue = result[2];
            power = result[5];
            result = null;
        }
        if (!resValue && !power) {
            return false;
        }
        dotIndex = resValue.indexOf('.');
        resValue = resValue.replace('.', '');
        resArr = resValue.split('');
        if (Number(power) >= 0) {
            const subres = resValue.substr(dotIndex);
            power = Number(power);
            // 幂数大于小数点后面的数字位数时，后面加0
            for (let i = 0; i < power - subres.length; i++) {
                resArr.push('0');
            }
            if (power - subres.length < 0) {
                resArr.splice(dotIndex + power, 0, '.');
            }
        } else {
            power = power.replace('-', '');
            power = Number(power);
            // 幂数大于等于 小数点的index位置, 前面加0
            for (let i = 0; i <= power - dotIndex; i++) {
                resArr.unshift('0');
            }
            const n = power - dotIndex >= 0 ? 1 : -(power - dotIndex);
            resArr.splice(n, 0, '.');
        }
    } else {
        return num;
    }
    resValue = resArr.join('');
    return sym + resValue;
}
/**
 * 数字自增到某一值动画
 * @param targetEle 目标元素
 * @param options 自定义配置
 * @returns
 */
export function NumAutoPlusAnimation(targetEle, options) {
    options = options || {};
    const $this = document.getElementById(targetEle);
    const time = options.time; // || $this.data('time') // 总时间--毫秒为单位
    const finalNum = options.num; // || $this.data('value') // 要显示的真实数值
    const regulator = options.regulator || 100; // 调速器，改变regulator的数值可以调节数字改变的速度
    const step = finalNum / (time / regulator); /* 每30ms增加的数值-- */
    let count = options.count; // 计数器
    if (options.percentum) {
        count = options.count2;
    }
    let initial: any = 0;

    const timer = setInterval(function () {
        // 递增 或 递减
        // if (count < finalNum) {
        count = Number(count) + Number(step);
        if (count >= finalNum) {
            clearInterval(timer);
            count = finalNum;
        }

        // } else {
        //     count = count - step;
        //     if (count <= finalNum) {
        //         clearInterval(timer);
        //         count = finalNum;
        //     }
        // }

        // t未发生改变的话就直接返回
        // 避免调用text函数，提高DOM性能
        let t = Math.floor(count) as any;
        t = numberFormat(t, 0);
        // if (t == initial) return;

        if (options.percentum) {
            initial = '(' + t + '%)';
        } else {
            initial = t;
        }

        $this.innerHTML = initial;
    }, 30);
}

/**
 * 数字自增到某一值动画
 * @param targetEle 目标元素
 * @param options 自定义配置
 * @returns
 */
export function NumAutoPlusAnimation2(targetEle, options) {
    options = options || {};
    const $this = document.getElementById(targetEle);
    const time = options.time; // || $this.data('time') // 总时间--毫秒为单位
    const finalNum = options.num; // || $this.data('value') // 要显示的真实数值
    const regulator = options.regulator || 100; // 调速器，改变regulator的数值可以调节数字改变的速度
    const step = finalNum / (time / regulator); /* 每30ms增加的数值-- */
    let count = 0; // 计数器
    let initial: any = 0;

    const timer = setInterval(function () {
        count = count + step;

        if (count >= finalNum) {
            clearInterval(timer);
            count = finalNum;
        }
        // t未发生改变的话就直接返回
        // 避免调用text函数，提高DOM性能
        const t = Math.floor(count);
        // if (t == initial) return;

        initial = t;

        $this.innerHTML = initial;
    }, 30);
}
// /**
//  * 一维数组转树形结构
//  * @param {*} list
//  * @param {*} id
//  * @param {*} parentId
//  */
// export function arrayToTree(arr, idStr, pidStr, chindrenStr) {
//     const r = [];
//     const hash = {};
//     const id = idStr;
//     const pid = pidStr;
//     const children = chindrenStr;
//     const len = arr.length;
//     for (let i = 0; i < len; i++) {
//         hash[arr[i][id]] = arr[i];
//     }
//     for (let j = 0; j < len; j++) {
//         const aVal = arr[j];
//         const hashVP = hash[aVal[pid]];
//         if (hashVP) {
//             !hashVP[children] && (hashVP[children] = []);
//             hashVP[children].push(aVal);
//         } else {
//             r.push(aVal);
//         }
//     }
//     return r;
// }
/**
 * 一维数组转树形结构
 * @param {Array} data
 * @param {Object} options
 */
export function arrayToTree(data, options?) {
    options = Object.assign(
        {
            id: 'id',
            parentId: 'parentId',
            children: 'children',
        },
        options
    );

    const map = {};
    const roots = [];

    data.forEach(item => {
        const id = item[options.id];
        const parentId = item[options.parentId];

        if (!map[id]) {
            // 使用浅拷贝来处理不能修改源数据的情况
            map[id] = Object.assign({}, item);
        } else {
            map[id] = Object.assign(map[id], item);
        }

        if (parentId === undefined || parentId === null || parentId === '' || parentId === 2) {
            // if (map[id].level && !map[id][options.children]) {
            //     map[id][options.children] = []
            // }
            // 处理根节点
            roots.push(map[id]);
        } else {
            if (!map[parentId]) {
                // 处理未出现在父级节点数组中的子节点
                map[parentId] = {};
            }
            if (!map[parentId][options.children]) {
                // 处理未定义子节点的情况
                map[parentId][options.children] = [];
            }
            // if (map[id].level) {
            //     map[id][options.children] = []
            // }
            map[parentId][options.children].push(map[id]);
        }
    });

    return roots;
}

export function treeToArray(list) {
    const data = XEUtils.clone(list, true);
    const result = [];
    data.forEach(item => {
        const loop = data => {
            result.push(data);
            const child = data.children;
            if (child) {
                for (let i = 0; i < child.length; i++) {
                    loop(child[i]);
                }
            }
        };
        loop(item);
    });
    return result;
}

export function recursivefilter(list, key, value) {
    const arr = XEUtils.clone(list, true);
    return arr.filter(item => {
        if (item[key] === value) {
            return false;
        }
        if (item.children && item.children.length > 0) {
            item.children = recursivefilter(item.children, key, value);
        }
        return true;
    });
}

/**
 * 获取当前环境下配置项
 * @param {string} field  配置项字段名
 * @return 字段值 转换大小写,转布尔,去除空格,字段丢失...
 * 待完善
 */
export function getConfigItem(field: string): any {
    let value = process.env.ENV_CONFIG === 'project' ? window.project_config[field] : process.env[field];
    if (field === 'WEB_DOCKING') {
        if (!value) {
            value = window.project_config.webDocking;
        }
        console.info(
            `%c ENV_CONFIG %c ${process.env.ENV_CONFIG} `,
            'padding: 1px; border-radius: 3px 0 0 3px; color: #fff; background:#606060',
            'padding: 1px; border-radius: 0 3px 3px 0; color: #fff; background:#1475b2'
        );
        console.info(
            `%c WEB_DOCKING %c ${value.toUpperCase()} `,
            'padding: 1px; border-radius: 3px 0 0 3px; color: #fff; background:#606060',
            'padding: 1px; border-radius: 0 3px 3px 0; color: #fff; background:#1475b2'
        );
        return value.toUpperCase(); // 转大写
    } else if (['WATERMARKING', 'SHOW_SECURITY', 'SHOW_MARQUEE'].includes(field)) {
        if (value === 'undefined' && field === 'WATERMARKING') {
            value = window.project_config.waterMarking;
        }
        if (value === 'undefined' && field === 'SHOW_SECURITY') {
            value = window.project_config.showSecurity;
        }
        if (value === 'undefined' && field === 'SHOW_MARQUEE') {
            value = window.project_config.SHOW_MARQUEE;
        }
        if (typeof value !== 'boolean') {
            // eslint-disable-next-line no-eval
            return eval(value); // 转布尔
        }
    } else if (field === 'BASE_URL_WS') {
        const api = process.env.ENV_CONFIG === 'project' ? window.project_config['BASE_URL_API'] : process.env['BASE_URL_API'];
        if (window.project_config.baseUrlWS || window.project_config.BASE_URL_WS) {
            return window.project_config.baseUrlWS || window.project_config.BASE_URL_WS;
        }
        return api.replace(/^http(s?)/g, 'ws$1'); // http(s) 转 ws(s)
    }
    return value ?? '';
}

/**
 * 对比版本号 部署自动清理缓存
 * @return 是否最新
 */
export function checkVersion() {
    return new Promise(resolve => {
        let url = '/static/version.json?v=';
        // Window Location 路径名 = '/YH/'
        if (getConfigItem('WEB_DOCKING') === 'MAXWEALTH' && window.location.pathname === '/YH/') {
            url = '/YH/static/version.json?v=';
        } else if (window.location.pathname === '/dist/') {
            url = '/dist/static/version.json?v=';
        }
        Axios.get(url + new Date().getTime(), {
            headers: { 'Cache-Control': 'no-store' },
            baseURL: window.location.origin,
        }).then((res: any) => {
            const version = res.data.version;
            const clientVersion = Number((document.querySelector('#Version') as any).content || '');
            console.info(
                '%c Build Date ' + '%c ' + moment(new Date(clientVersion)).format('YYYY-MM-DD hh:mm:ss') + ' ',
                'padding: 1px; border-radius: 3px 0 0 3px;color: #fff; background:#606060',
                'padding: 1px; border-radius: 0 3px 3px 0;color: #fff; background:#1475b2'
            );
            console.info(
                '%c Last Build Date ' + '%c ' + moment(new Date(version)).format('YYYY-MM-DD hh:mm:ss') + ' ',
                'padding: 1px; border-radius: 3px 0 0 3px; color: #fff; background:#606060',
                'padding: 1px; border-radius: 0 3px 3px 0; color: #fff; background:#1475b2'
            );
            resolve(version === clientVersion);
        });
    });
}

/**
 * 对比项目配置文件 部署自动清理缓存
 * @return 是否最新
 */
export function checkProjectConfig() {
    return new Promise(resolve => {
        let url = '/static/project-config.js';
        if (getConfigItem('WEB_DOCKING') === 'MAXWEALTH' && window.location.pathname === '/YH/') {
            url = '/YH/static/project-config.js';
        } else if (window.location.pathname === '/dist/') {
            url = '/dist/static/project-config.js';
        }
        Axios.get(url, {
            headers: { 'Cache-Control': 'no-cache' },
            baseURL: window.location.origin,
        }).then((res: any) => {
            // eslint-disable-next-line no-eval
            const code = JSON.stringify(eval(res.data));
            resolve(code === JSON.stringify(window.project_config)); // 必等于 true 因为 no-cache
        });
    });
}

/**
 * 限定指令数量
 * @param changeFlag 证券变动方向，用于判断买入相关还是卖出相关, 0:没有变动，1：增加，2：减少
 * @param amountLimit
 * @param orderAmount
 * @returns
 */

export function handleLimitAmount(changeFlag: string, amountLimit: any, orderAmount: any) {
    if (orderAmount === '' || orderAmount === undefined) {
        return true;
    }
    // 判断买入相关还是卖出相关
    if (changeFlag == '1') {
        if (amountLimit?.buyUnit && orderAmount % amountLimit?.buyUnit !== 0) {
            console.log(amountLimit, 'amountLimit');
            yh_message_warn(`“指令数量”应为“最小买卖单位：${amountLimit.buyUnit}”的整数倍！`);
            console.log('买入');
            return false;
        }
        if (amountLimit?.buyDownLimitedAmount && Number(orderAmount) < Number(amountLimit?.buyDownLimitedAmount)) {
            yh_message_warn(`“指令数量”应大于等于“最低数量限额：${amountLimit?.buyDownLimitedAmount}”！`);
            return false;
        }
    } else if (changeFlag == '2') {
        if (amountLimit?.saleUnit && orderAmount % amountLimit?.saleUnit !== 0) {
            yh_message_warn(`“指令数量”应为“最小买卖单位：${amountLimit.saleUnit}”的整数倍！`);
            console.log('卖出');
            return false;
        }
        if (amountLimit?.saleDownLimitedAmount && Number(orderAmount) < Number(amountLimit?.saleDownLimitedAmount)) {
            yh_message_warn(`“指令数量”应大于等于“最低数量限额：${amountLimit?.saleDownLimitedAmount}”！`);
            return false;
        }
    }

    return true;
}

/**
 * 反算指令数量
 */
export function handleInverseAmount(changeFlag: string, amountLimit: any, orderAmount: any) {
    if (orderAmount === '' || orderAmount === undefined) {
        return '';
    }
    let amount: any = orderAmount;
    let multiple: number = 1;

    // 判断买入相关还是卖出相关
    if (changeFlag == '1') {
        if (amountLimit?.buyDownLimitedAmount && Number(orderAmount) < Number(amountLimit?.buyDownLimitedAmount)) {
            yh_message_warn(`“指令数量”应大于等于“最低数量限额：${amountLimit?.buyDownLimitedAmount}”！`);

            return '';
        }

        if (amountLimit?.buyUnit) {
            if (orderAmount % amountLimit?.buyUnit !== 0) {
                // 向下取整
                multiple = Math.floor(orderAmount / amountLimit?.buyUnit);
                amount = amountLimit?.buyUnit * multiple;
            } else {
                amount = orderAmount;
            }
        } else {
            amount = orderAmount;
        }
    } else if (changeFlag == '2') {
        if (amountLimit?.saleDownLimitedAmount && Number(orderAmount) < Number(amountLimit?.saleDownLimitedAmount)) {
            yh_message_warn(`“指令数量”应大于等于“最低数量限额：${amountLimit?.saleDownLimitedAmount}”！`);
            return '';
        }

        if (amountLimit?.saleUnit) {
            if (orderAmount % amountLimit?.saleUnit !== 0) {
                multiple = Math.floor(orderAmount / amountLimit?.saleUnit);
                amount = amountLimit?.saleUnit * multiple;
            } else {
                amount = orderAmount;
            }
        } else {
            amount = orderAmount;
        }
    }
    return amount;
}
/**
 * 限定指令数量(交易所大宗、上交所固收)
 * @param changeFlag 证券变动方向，用于判断买入相关还是卖出相关, 0:没有变动，1：增加，2：减少
 * @param amountLimit
 * @param orderAmount
 * @returns
 */

export function handleLimitAmount1(changeFlag: string, amountLimit: any, unitLimit: any, orderAmount: any) {
    if (orderAmount === '' || orderAmount === undefined) {
        return true;
    }
    if (unitLimit !== '' && orderAmount % unitLimit !== 0) {
        console.log(amountLimit, 'amountLimit');
        yh_message_warn(`“指令数量”应为“最小买卖单位：${unitLimit}”的整数倍！`);
        return false;
    }
    // 判断买入相关还是卖出相关
    if (changeFlag == '1') {
        if (amountLimit?.buyDownLimitedAmount && Number(orderAmount) < Number(amountLimit?.buyDownLimitedAmount)) {
            yh_message_warn(`“指令数量”应大于等于“最低数量限额：${amountLimit?.buyDownLimitedAmount}”！`);
            return false;
        }
    } else if (changeFlag == '2') {
        if (amountLimit?.saleDownLimitedAmount && Number(orderAmount) < Number(amountLimit?.saleDownLimitedAmount)) {
            yh_message_warn(`“指令数量”应大于等于“最低数量限额：${amountLimit?.saleDownLimitedAmount}”！`);
            return false;
        }
    }

    return true;
}

/**
 * 反算指令数(交易所大宗、上交所固收)
 */
export function handleInverseAmount1(changeFlag: string, amountLimit: any, unitLimit: any, orderAmount: any) {
    // debugger;
    if (orderAmount === '' || orderAmount === undefined) {
        return '';
    }
    let amount: any;
    let multiple: number = 1;
    console.log(orderAmount, unitLimit, 'orderAmount');

    // 判断买入相关还是卖出相关
    if (changeFlag == '1') {
        if (amountLimit?.buyDownLimitedAmount && Number(orderAmount) < Number(amountLimit?.buyDownLimitedAmount)) {
            yh_message_warn(`“指令数量”应大于等于“最低数量限额：${amountLimit?.buyDownLimitedAmount}”！`);

            return '';
        }
    } else if (changeFlag == '2') {
        if (amountLimit?.saleDownLimitedAmount && Number(orderAmount) < Number(amountLimit?.saleDownLimitedAmount)) {
            yh_message_warn(`“指令数量”应大于等于“最低数量限额：${amountLimit?.saleDownLimitedAmount}”！`);
            return '';
        }
    }
    if (unitLimit == 0) {
        amount = '';
        return amount;
    }

    if (unitLimit !== '') {
        if (orderAmount % unitLimit !== 0) {
            // 向下取整
            multiple = Math.floor(orderAmount / unitLimit);
            amount = unitLimit * multiple;
        } else {
            amount = orderAmount;
        }
    } else {
        amount = orderAmount;
    }
    return amount;
}

/**
 * 是否是O32计算页面
 */
// export function isCalcO32() {
//     console.log('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
//     // console.log(TagsViewModule.getActive);
//     // todo  换成O32路由
//     // return TagsViewModule.getActive == '/risk/setting/itemSetting';
//     // console.log(getResourceCode(window.location.href));
//     const value = getResourceCode(window.location.href) === 'M_205';
//     console.log(window.location.href, value, 'eeeeeeeeeeee');
//     return value;
//     // return window.location.href == '/risk/setting/itemSetting';
// }

// 根据docking来判断是否展示字段
export function showParamByDocking() {
    let isShow = true;
    const docking = getConfigItem('WEB_DOCKING');
    if (docking === 'MAXWEALTH') {
        isShow = false;
    }
    return isShow;
}

/*
 * 将base64转换成可用formdata提交的文件
 * @param {String} urlData base64的url
 */
export function convertBase64UrlToBlob(urlData) {
    // 去掉url的头，并转换为byte
    var bytes = window.atob(urlData.split(',')[1]);
    // 处理异常,将ascii码小于0的转换为大于0
    var ab = new ArrayBuffer(bytes.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i);
    }
    return new Blob([ab], { type: 'image/png' });
}

/**
 * 一维数组转树形结构
 * @param {Array} data
 * @param {Object} options
 */
export function ZCarrayToTree(data, options?) {
    options = Object.assign(
        {
            id: 'id',
            parentId: 'parentId',
            children: 'children',
        },
        options
    );

    const map = {};
    const roots = [];
    data.forEach(item => {
        const id = item[options.id];
        const parentId = item[options.parentId];

        if (!map[id]) {
            // 使用浅拷贝来处理不能修改源数据的情况
            map[id] = Object.assign({}, item);
        } else {
            map[id] = Object.assign(map[id], item);
        }

        if (parentId === undefined || parentId === null || parentId === '' || parentId === 2 || parentId === ' ') {
            // if (map[id].level && !map[id][options.children]) {
            //     map[id][options.children] = []
            // }
            // 处理根节点
            roots.push(map[id]);
        } else {
            if (!map[parentId]) {
                // 处理未出现在父级节点数组中的子节点
                map[parentId] = {};
            }
            if (!map[parentId][options.children]) {
                // 处理未定义子节点的情况
                map[parentId][options.children] = [];
            }
            // if (map[id].level) {
            //     map[id][options.children] = []
            // }
            map[parentId][options.children].push(map[id]);
        }
    });

    return roots;
}

/**
 * 跳转路由
 * @msg
 * {
 *      title: '投资风险设置', 
 *      path: '/risk/setting/itemSetting',
 *      type: '0', // 0-内部 1-外部 (内部是指 待跳转页面代码 在这套vue里)
 *      params: { entryCode: 'YH001' } // string | any 需要带进跳转页面的参数
 *  };
 */
export function jumpRouter(msg) {
    console.log('跳转路由:', msg)
    const menu = getUser().resources.find(i => i.menuUrl == msg.path);
    if (!menu) {
        this.yh_message_error(`无${msg.title}页面权限,不可跳转!`);
        return;
    }
    top.window.postMessage(msg, '*');
}
